package com.leo.result

/**
 * 返回对象的封装
 *
 * @author mingsan
 * @date 2019/9/28
 */
public class ResultEntity<T> {
    /**
     * 响应码
     * 0的时候没数据
     * 1的时候有数据
     */
    var code = 0

    /**
     * 提示信息
     */
    var message: String? = null

    /**
     * 业务数据
     */
    var data: T? = null
        private set

    interface ResultBuilder<T> {
        /**
         * 是否有数据
         *
         * @param code 响应码
         * @return ResultBuilder<T>
        </T> */
        fun code(code: ResultCode): ResultBuilder<T>

        /**
         * 默认Message 配置
         */
        fun message(message: String):ResultBuilder<T>

        /**
         * Data
         *
         * @param data 数据
         * @return ResultBuilder<T>
        </T> */
        fun data(data: T): ResultBuilder<T>

        /**
         * Result
         *
         * @return Result<T>
        </T> */
        fun build(): ResultEntity<T>
    }

    internal class DefaultBuilder<T> : ResultBuilder<T> {
        private val resultEntity = ResultEntity<T>()

        /**
         * 是否有数据
         *
         * @param code 响应码
         * @return ResultBuilder<T>
        </T> */
        override fun code(code: ResultCode): ResultBuilder<T> {
            resultEntity.code = code.code
            resultEntity.message = code.message
            return this
        }

        override fun data(data: T): ResultBuilder<T> {
            resultEntity.setData(data)
            return this
        }

        override fun build(): ResultEntity<T> {
            return resultEntity
        }

        /**
         * 默认Message 配置
         */
        override fun message(message: String): ResultBuilder<T> {
            resultEntity.code = 0
            resultEntity.message = message
            return this
        }
    }

    fun setData(data: T) {
        this.data = data
    }

    override fun toString(): String {
        return ("{\"Result\":{"
                + "\"code\":"
                + code
                + ",\"message\":\""
                + message + '\"'
                + ",\"data\":"
                + data
                + "}}")
    }

    companion object {


        fun <T> success(data: T, code: ResultCode = ResultCode.Success): ResultEntity<T> {
            val resultBuilder: ResultBuilder<T> = DefaultBuilder()

            return resultBuilder.code(code).data(data).build()
        }


        fun <T> fail(resultCode: ResultCode = ResultCode.NoData):ResultEntity<T>{
            val resultBuilder: ResultBuilder<T> = DefaultBuilder()
            resultBuilder.code(resultCode)
            return resultBuilder.build()
        }

        fun <T> fail(message:String?):ResultEntity<T>{
            val resultBuilder: ResultBuilder<T> = DefaultBuilder()
            message?.let {
                resultBuilder.message(it)
            }
            return resultBuilder.build()
        }
    }
}
